#include "io/sk_file.h"
#include "mem/sk_mem.h"
#include "util/sk_string.h"
//Creates a new file for use
//Opens a new existing file for use

struct SK_FILE{
#ifdef WIN32_PC
	HANDLE m_handle;
#endif	
};

SK_FILE * SK_FILE_open(const SK_WCHAR * pszfileName,SK_FILE_OPENMODE mode)
{
#ifdef WIN32_PC
	SK_UINT32 access = GENERIC_READ;
	HANDLE handle = INVALID_HANDLE_VALUE;
	if (mode == EOPEN_FOR_WRITE)
	{
		access = GENERIC_READ | GENERIC_WRITE;
	}
	handle = CreateFileW((LPCWSTR)pszfileName, access, FILE_SHARE_READ,NULL, OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL, 0); 
	if (handle != INVALID_HANDLE_VALUE)
	{
		SK_FILE * pskFIle = (SK_FILE *)SK_MEM_malloc(sizeof(SK_FILE));
		pskFIle->m_handle= handle;
		return pskFIle;
	}
	else
	{
		return NULL;
	}
#endif

}

//Closes a file which has been opened for use
void SK_FILE_close(SK_FILE *pFile)
{
	if (pFile != NULL)
	{
#ifdef WIN32_PC
		CloseHandle(pFile->m_handle);
#endif
		SAFE_FREE(pFile);
	}

}

//Sets the position to a desired point in the file,if ok return 0 else non-zero
SK_INT32 SK_FILE_seek(SK_FILE *pFile,SK_INT32 nOffset,SK_FILE_SEEKPOS nPos)
{
	if (pFile != NULL)
	{
#ifdef WIN32_PC
		SK_INT32 pos = FILE_BEGIN;
		if (nPos == ESEEK_END)
		{
			pos = FILE_END;
		}
		else if(nPos == ESEEK_CURRENT)
		{
			pos = FILE_CURRENT;
		}
		return SetFilePointer(pFile->m_handle,nOffset,NULL,pos);
#endif
	}
	else
	{
		return -1;
	}

}

//Gives the current position in the file
SK_INT32 SK_FILE_tell(SK_FILE *pFile)
{
	return SK_FILE_seek(pFile,0,ESEEK_CURRENT);
}

SK_INT32 SK_FILE_read(SK_FILE *o,void *buf, SK_UINT32 len)
{
	if (o != NULL)
	{
#ifdef WIN32_PC
		SK_UINT32 readed = 0;
		SK_BOOL b =	(SK_BOOL)ReadFile(o->m_handle,buf,len,(LPDWORD)&readed,NULL);
		if (b)
		{
			return readed;
		}
		else
		{
			return -1;
		}
#endif
	}
	else
	{
		return -1;
	}
}

SK_INT32 SK_FILE_write(SK_FILE *o,const void *buf, SK_UINT32 len)
{
	if (o != NULL)
	{
#ifdef WIN32_PC
		SK_UINT32 written = 0;
		SK_BOOL b = (SK_BOOL)WriteFile(o->m_handle,buf,len,(LPDWORD)&written,NULL);
		if (b)
		{
			return written;
		}
		else
		{
			return -1;
		}
#endif
	}
	else
	{
		return -1;
	}
}

//Sets the position to the begining of the file
void SK_FILE_rewind(SK_FILE *pFile)
{
	if (pFile != NULL)
	{
		SK_FILE_seek(pFile,0,ESEEK_BEGIN);
	}

}

SK_UINT32 SK_FILE_getLength(SK_FILE *pFile)
{
	if (pFile != NULL)
	{
#ifdef WIN32_PC
		return GetFileSize(pFile->m_handle,NULL);
#endif
	}
	else
	{
		return 0;
	}

}
//////////////////////////////////////////////////////////////////////////



SK_BOOL SK_FILE_isExist(const SK_WCHAR * pszPath)
{
#ifdef WIN32_PC
	WIN32_FIND_DATAW fd;
	HANDLE hFind = FindFirstFileW(pszPath,&fd);
	if (hFind != INVALID_HANDLE_VALUE)
	{
		FindClose(hFind);
		return TRUE;
	}
	else
	{
		return FALSE;
	}
#endif
}



SK_BOOL SK_FILE_createDir(const SK_WCHAR * pszDirPath)
{
#ifdef WIN32_PC
	SK_INT32 result =  CreateDirectoryW(pszDirPath,NULL);
	return result == 0 ? FALSE : TRUE;
#endif
}

SK_BOOL SK_FILE_deleteDir(const SK_WCHAR * pszDirPath)
{
#ifdef WIN32_PC
	SK_INT32 result =  RemoveDirectoryW(pszDirPath);
	return result == 0 ? FALSE : TRUE;
#endif
}
SK_BOOL SK_FILE_deleteFile(const SK_WCHAR * pszDirPath)
{
#ifdef WIN32_PC
	SK_INT32 result =  DeleteFileW(pszDirPath);
	return result == 0 ? FALSE : TRUE;
#endif
}

SK_INT32 SK_FILE_listSubDirNames(const SK_WCHAR * pszDirPath,SK_WCHAR * subDirs[],SK_INT32 len)
{
#ifdef WIN32_PC
	SK_INT32 count = 0;

	WIN32_FIND_DATAW fd;
	HANDLE hFind;
	SK_WCHAR *path = SK_MEM_malloc(SK_strlen(pszDirPath) + 2);
	SK_strcpy(path,pszDirPath);
	hFind = FindFirstFileW(path,&fd);
	if (hFind != INVALID_HANDLE_VALUE)
	{
		do 
		{
			if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{
				if (count < len)
				{
					SK_strcpy(subDirs[count],fd.cFileName);
					count ++;
				}
				else
				{
					break;
				}
			}
		} while (FindNextFileW(hFind,&fd));

		FindClose(hFind);
	}
	else
	{
		count = -1;
	}
	return count;
#endif
}



SK_INT32 SK_FILE_listSubFileNames(const SK_WCHAR * pszDirPath,SK_WCHAR * subFiles[],SK_INT32 len)
{
#ifdef WIN32_PC
	SK_INT32 count = 0;

	WIN32_FIND_DATAW fd;
	HANDLE hFind;
	SK_WCHAR *path = SK_MEM_malloc(SK_strlen(pszDirPath) + 2);
	SK_strcpy(path,pszDirPath);
	hFind = FindFirstFileW(path,&fd);
	if (hFind != INVALID_HANDLE_VALUE)
	{
		do 
		{
			if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
			{
				if (count < len)
				{
					SK_strcpy(subFiles[count],fd.cFileName);
					count ++;
				}
				else
				{
					break;
				}
			}
		} while (FindNextFileW(hFind,&fd));

		FindClose(hFind);
	}
	else
	{
		count = -1;
	}
	return count;
#endif
}

SK_BOOL SK_FILE_copyFile(const SK_WCHAR * des,const SK_WCHAR * src,SK_BOOL cover)
{
#ifdef WIN32_PC
	return (SK_BOOL) CopyFileW(src,des,cover);
#endif
}